package com.czh.service.impl;

import com.aliyuncs.ram.model.v20150501.GetUserResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.czh.domain.ResponseResult;
import com.czh.domain.dto.*;
import com.czh.domain.entity.Role;
import com.czh.domain.entity.User;
import com.czh.domain.entity.UserRole;
import com.czh.domain.vo.*;
import com.czh.enums.AppHttpCodeEnum;
import com.czh.hander.exception.SystemException;
import com.czh.mapper.UserMapper;
import com.czh.service.RoleService;
import com.czh.service.UserRoleService;
import com.czh.service.UserService;
import com.czh.utils.BeanCopyPlusUtils;
import com.czh.utils.BeanCopyUtils;
import com.czh.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleService roleService;
    @Override
    public ResponseResult<UserInfoVo> userInfo() {
        Long userId = SecurityUtils.getUserId();
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(getById(userId), UserInfoVo.class);
        return ResponseResult.okResult(userInfoVo);
    }

    @Override
    public ResponseResult<Object> updateUserInfo(User user) {
        updateById(user);
        return ResponseResult.okResult();
    }
    @Override
    public ResponseResult<Object> register(User user) {
        judgeUser(user);
        String encode = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(encode);
        save(user);
        //前台注册的用户应该都是普通用户
        userRoleService.save(new UserRole(user.getId(), 2L));
        return ResponseResult.okResult();
    }
    //admin
    @Override
    public ResponseResult<UserPageVo> userPage(Integer pageNum, Integer pageSize, QueryUserDto queryUserDto) {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.like(StringUtils.hasText(queryUserDto.getUserName()),User::getUserName,queryUserDto.getUserName()).
                like(StringUtils.hasText(queryUserDto.getPhoneNumber()),User::getPhoneNumber,queryUserDto.getPhoneNumber()).
                eq(StringUtils.hasText(queryUserDto.getStatus()),User::getStatus,queryUserDto.getStatus());
        Page<User> userPage = new Page<>(pageNum, pageSize);
        page(userPage,userLambdaQueryWrapper);

        List<UserVo> userVo = BeanCopyPlusUtils.copyPropertiesList(userPage.getRecords(), UserVo.class);
        return ResponseResult.okResult(new UserPageVo(userVo,userPage.getTotal()));
    }

    @Override
    public ResponseResult<Object> addUser(AddUserDto addUserDto) {
        User user = BeanCopyPlusUtils.copyProperties(addUserDto, User.class);
        judgeUser(user);
        String encode = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(encode);
        save(user);
        List<UserRole> userRoleList = addUserDto.getRoleIds().stream().
                map(roleId -> new UserRole(user.getId(), roleId)).
                collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<Object> deleteUser(Long id) {
        removeById(id);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<UserUpOldInfoVo> userOldInfo(Long id) {
        LambdaQueryWrapper<UserRole> userRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userRoleLambdaQueryWrapper.eq(UserRole::getUserId,id);
        List<Long> roleIds = userRoleService.list(userRoleLambdaQueryWrapper).stream().map(UserRole::getRoleId).collect(Collectors.toList());
        List<Role> roles = roleService.list();
        UserOldInfoVo user = BeanCopyPlusUtils.copyProperties(getById(id), UserOldInfoVo.class);
        return ResponseResult.okResult(new UserUpOldInfoVo(roleIds,roles,user));
    }

    @Override
    public ResponseResult<Object> updateUser(UpdateUserDto updateUserDto) {
        User user = BeanCopyPlusUtils.copyProperties(updateUserDto, User.class);
        updateById(user);
        LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleService.remove(userRoleWrapper.eq(UserRole::getUserId,updateUserDto.getId()));

        List<UserRole> collect = updateUserDto.getRoleIds().stream().
                map(roleId -> new UserRole(updateUserDto.getId(), roleId)).collect(Collectors.toList());
        userRoleService.saveBatch(collect);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<Object> changeStatus(ChangeUserStatusDto statusDto) {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId,statusDto.getUserId()).set(User::getStatus,statusDto.getStatus());
        update(updateWrapper);
        return ResponseResult.okResult();
    }

    /**
     * 检查用户信息
     * @param user 新增用户
     */
    public void judgeUser(User user){
        if (user.getUserName() == null) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        if (user.getPassword() == null) {
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if (user.getEmail() == null) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }
        if (user.getNickName() == null) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        // 判断用户名、邮箱、手机号是否已存在
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (count(userLambdaQueryWrapper.eq(User::getUserName, user.getUserName())) > 0) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        userLambdaQueryWrapper.clear();
        if (count(userLambdaQueryWrapper.eq(User::getEmail, user.getEmail())) > 0) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        userLambdaQueryWrapper.clear();
        if (count(userLambdaQueryWrapper.eq(User::getPhoneNumber, user.getPhoneNumber())) > 0) {
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
    }
}
